iT邦幫忙

2026 iThome 鐵人賽

DAY 5
1

Day 4 已經定義好 8 個 SQLAlchemy Model。今天把它們建立成真正的 SQLite 資料庫,插入測試資料,再用查詢腳本確認資料可以讀出來。

SQLite 以單一檔案保存資料,不需要另外啟動資料庫伺服器。對目前的開發階段來說,這可以先把 API 流程跑通。之後如果部署需求改變,再調整連線設定。

今天要完成的三件事

  1. 建立 database.py,設定 SQLAlchemy 與 SQLite 的連線。
  2. 執行初始化腳本,建立資料表與測試資料。
  3. 執行驗證腳本,確認資料能正確讀取。

進入 backend:

cd backend
python -m pip install sqlalchemy python-dotenv

確認 SQLAlchemy:

python -c "import sqlalchemy; print(sqlalchemy.__version__)"

步驟 1:建立 database.py

檔案位置:backend/database.py

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from models import Base

DATABASE_URL = "sqlite:///./app.db"

engine = create_engine(
    DATABASE_URL,
    connect_args={"check_same_thread": False}
)

SessionLocal = sessionmaker(
    autocommit=False,
    autoflush=False,
    bind=engine
)


def init_db():
    """建立所有表"""
    Base.metadata.create_all(bind=engine)


def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

DATABASE_URL 指向 backend 目錄下的 app.db。create_engine 建立資料庫引擎,SessionLocal 用來產生資料庫 Session。init_db 會依照 Day 4 的 Model 建立資料表,get_db 則提供給 FastAPI 的依賴注入使用。

步驟 2:建立初始化腳本

檔案位置:backend/init_db.py

from database import SessionLocal, init_db
from models import User, Profile, Goal, Plan, Task, ProgressLog
from datetime import datetime, timedelta


def init_database():
    """初始化資料庫"""
    init_db()
    print("✓ 所有表已建立")

    db = SessionLocal()

    try:
        if db.query(User).first() is not None:
            print("✓ 資料庫已初始化過,跳過插入")
            return

        user = User(
            email="demo@example.com",
            password_hash="hashed_password_here"
        )
        db.add(user)
        db.flush()
        print(f"✓ 建立測試使用者: {user.email}")

        profile = Profile(
            user_id=user.id,
            level="初級",
            available_hours=10.0,
            learning_topic="AWS Solutions Architect 認證"
        )
        db.add(profile)
        print("✓ 建立學習檔案")

        goal = Goal(
            user_id=user.id,
            title="3 個月內通過 AWS SA 認證",
            deadline=datetime.now() + timedelta(days=90),
            description="準備 AWS Solutions Architect Associate 考試",
            status="進行中"
        )
        db.add(goal)
        db.flush()
        print("✓ 建立學習目標")

        plan = Plan(
            user_id=user.id,
            goal_id=goal.id,
            title="AWS 12 週密集課程",
            duration_weeks=12,
            status="進行中",
            content={"weeks": [
                {"week": 1, "topic": "EC2 與網路基礎"},
                {"week": 2, "topic": "S3 與儲存"},
                {"week": 3, "topic": "資料庫與 RDS"}
            ]}
        )
        db.add(plan)
        db.flush()
        print("✓ 建立學習計畫")

        for day in range(1, 6):
            task = Task(
                plan_id=plan.id,
                day=day,
                title=f"Day {day}: 學習 AWS 核心服務",
                description=f"今天的主題是第 {day} 個核心主題",
                estimated_hours=2.0,
                status="待做" if day > 1 else "進行中",
                deadline=datetime.now() + timedelta(days=day)
            )
            db.add(task)
        print("✓ 建立 5 個測試任務")

        first_task = db.query(Task).filter(Task.day == 1).first()
        if first_task:
            log = ProgressLog(
                task_id=first_task.id,
                actual_hours=1.5,
                notes="比預期快一點,概念理解得不錯",
                completed_at=datetime.now(),
                difficulty_rating=3
            )
            db.add(log)
            print("✓ 建立進度記錄")

        db.commit()
        print("\\n✅ 資料庫初始化完成!")
        print("✅ 資料庫檔案位置: ./app.db")

    except Exception as error:
        db.rollback()
        print(f"❌ 初始化失敗: {error}")
        raise
    finally:
        db.close()


if __name__ == "__main__":
    init_database()

這個腳本會建立所有資料表,再新增一個測試使用者、學習檔案、目標、計畫、5 個任務和一筆進度紀錄。執行前會先檢查 users 是否已有資料,避免重複插入。

執行:

cd backend
python init_db.py

預期輸出:

✓ 所有表已建立
✓ 建立測試使用者: demo@example.com
✓ 建立學習檔案
✓ 建立學習目標
✓ 建立學習計畫
✓ 建立 5 個測試任務
✓ 建立進度記錄

✅ 資料庫初始化完成!
✅ 資料庫檔案位置: ./app.db

步驟 3:驗證資料庫

檔案位置:backend/verify_db.py

from database import SessionLocal
from models import User, Profile, Goal, Plan, Task, ProgressLog


def verify_database():
    """驗證資料庫資料"""
    db = SessionLocal()

    try:
        users = db.query(User).all()
        print(f"👤 使用者數量: {len(users)}")
        for user in users:
            print(f"   - Email: {user.email}")

        profiles = db.query(Profile).all()
        print(f"\\n📚 學習檔案數量: {len(profiles)}")
        for profile in profiles:
            print(
                f"   - 等級: {profile.level}, "
                f"每週時間: {profile.available_hours} 小時"
            )

        goals = db.query(Goal).all()
        print(f"\\n🎯 學習目標數量: {len(goals)}")
        for goal in goals:
            print(f"   - {goal.title} (截止: {goal.deadline})")

        plans = db.query(Plan).all()
        print(f"\\n📋 學習計畫數量: {len(plans)}")
        for plan in plans:
            print(f"   - {plan.title} ({plan.duration_weeks} 週)")

        tasks = db.query(Task).all()
        print(f"\\n✅ 任務數量: {len(tasks)}")
        for task in tasks[:3]:
            print(f"   - Day {task.day}: {task.title}")

        logs = db.query(ProgressLog).all()
        print(f"\\n📊 進度記錄數量: {len(logs)}")
        for log in logs:
            print(
                f"   - 花費時間: {log.actual_hours} 小時, "
                f"難度: {log.difficulty_rating}/5"
            )

        print("\\n✅ 資料庫驗證完成!所有表正常運作。")

    except Exception as error:
        print(f"❌ 驗證失敗: {error}")
    finally:
        db.close()


if __name__ == "__main__":
    verify_database()

執行:

python verify_db.py

這個腳本會分別查詢使用者、學習檔案、目標、計畫、任務和進度紀錄,確認表之間的關聯可以正常使用。

用 SQLite Browser 查看

如果想用圖形介面查看資料表,可以從 https://sqlitebrowser.org/ 下載 SQLite Browser。

開啟後:

  1. 選擇 File → Open Database。
  2. 開啟 backend/app.db。
  3. 查看資料表結構與測試資料。

常見問題

ModuleNotFoundError

確認 backend 內有 Day 4 的 models.py,並重新安裝 SQLAlchemy:

python -m pip install sqlalchemy

app.db 在哪裡?

執行 init_db.py 後,檔案會出現在 backend 目錄下。

可以重新初始化嗎?

可以刪除 app.db,再執行 python init_db.py。這會清除目前的測試資料,因此正式資料庫不要用這種方式重建。

為什麼 SQLite 比 PostgreSQL 慢?

SQLite 適合目前的單機開發和測試。若之後需要多個服務同時寫入,再評估 PostgreSQL 或 MySQL,並將 DATABASE_URL 改成對應的連線設定。

Day 5 完成檢查

今天完成:

  • database.py 的 SQLAlchemy 連線設定
  • init_db.py 初始化腳本
  • 測試使用者、計畫、任務與進度資料
  • verify_db.py 查詢驗證
  • 用 SQLite Browser 查看資料表

進度如下:

Day 1 ✓ 產品定義完成
Day 2 ✓ 開發環境準備
Day 3 ✓ 專案架構設計
Day 4 ✓ 資料庫設計
Day 5 ✓ SQLite 資料庫建置
Day 6 ⬜ FastAPI 基礎
Day 7+ ⬜ API 實作

明天把資料庫接到 FastAPI,建立第一批 API 端點。


上一篇
Day 4:資料庫設計
下一篇
Day 6:FastAPI 基礎
系列文
30天用 Claude Code + LangGraph 實作個人化 AI 學習教練10
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
tsengyulun
iT邦新手 5 級 ‧ 2026-09-19 17:29:32

今天幾點起床

pst iT邦新手 5 級 ‧ 2026-09-19 17:30:46 檢舉

真是有意義的問題

pst iT邦新手 5 級 ‧ 2026-09-19 17:31:03 檢舉

好啦12.啊

我贏了 我 10:30

我要留言

立即登入留言